package com.upb.webserver.application;

import com.upb.webserver.account.AccountService;
import com.upb.webserver.common.exception.OperationException;
import com.upb.webserver.common.pojo.account.AccountCommon;
import com.upb.webserver.common.pojo.application.ReqModifyAppOrg;
import com.upb.webserver.common.pojo.base.BasePageResponse;
import com.upb.webserver.common.pojo.base.BaseResponse;
import com.upb.webserver.common.pojo.order.ApplicationUnionOrder;
import com.upb.webserver.common.pojo.order.ReqAddNode2AppVo;
import com.upb.webserver.common.pojo.order.ReqAddWorkOrderOfNewApplicationVO;
import com.upb.webserver.common.returncode.ConstantCode;
import com.upb.webserver.common.tools.JsonUtils;
import com.upb.webserver.dao.entity.TbApplication;
import com.upb.webserver.order.OrderService;
import com.upb.webserver.org.OrgManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Set;

/**
 * public controller for fisco application(group/channel) create api
 */
@Slf4j
@RestController
@RequestMapping(value = "application")
public class ApplicationController {


    @Autowired
    private AccountService accountService;
    @Autowired
    private OrgManager orgManager;
    @Autowired
    private OrderService orderService;
    @Autowired
    private ApplicationService applicationService;
    @Autowired
    private ApplicationManager applicationManager;


    //节点加入新群组
    @PostMapping(value = "work-order-of-add-node")
    public BaseResponse addWorkOrderOfAddNode(@RequestBody @Valid ReqAddNode2AppVo reqAddNode2AppVo, HttpServletRequest request) {
        log.info("start exec method [addWorkOrderOfAddNode]. param:{}", JsonUtils.objToString(reqAddNode2AppVo));
        AccountCommon accountCommon = accountService.getAccountCommon(request);
        BaseResponse baseResponse = orderService.addWorkOrderOfaddNode2App(accountCommon, reqAddNode2AppVo);
        log.info("success exec method [addWorkOrderOfAddNode]. baseResponse:{}", JsonUtils.objToString(baseResponse));
        return baseResponse;
    }


    /**
     * @param param
     * @param result
     * @param request
     * @return
     */
    @PostMapping(value = "work-order-of-create-application/apply")
    public BaseResponse addWorkOrderOfNewApplication(@RequestBody @Valid ReqAddWorkOrderOfNewApplicationVO param, BindingResult result, HttpServletRequest request) throws OperationException {
        log.info("start exec method [addWorkOrderOfNewApplication]. param:{}", JsonUtils.objToString(param));
        AccountCommon accountCommon = accountService.getAccountCommon(request);
        ApplicationUnionOrder rsp = orderService.addWorkOrderOfNewApplication(accountCommon.getPlatform(), accountCommon.getId(), accountCommon.getAccount(), param);
        BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS);
        baseResponse.setData(rsp);
        log.info("success exec method [addWorkOrderOfNewApplication]. baseResponse:{}", JsonUtils.objToString(baseResponse));
        return baseResponse;
    }


    /**
     * @param workOrderId
     * @param request
     * @return
     */
    @PatchMapping(value = "work-order-of-create-application/{workOrderId}/receive")
    public BaseResponse receiveInvitationToCreateApplication(@PathVariable("workOrderId") Integer workOrderId, HttpServletRequest request) {
        log.info("start exec method [receiveInvitationToCreateApplication]. workOrderId:{}", workOrderId);
        AccountCommon accountCommon = accountService.getAccountCommon(request);
        orderService.updateWorkOrderOfNewApplication(accountCommon.getPlatform(), accountCommon.getId(), accountCommon.getAccount(), workOrderId);
        log.info("success exec method [receiveInvitationToCreateApplication].");
        return new BaseResponse(ConstantCode.SUCCESS);
    }


    /**
     * @param workOrderId
     * @param request
     * @return
     */
    @PatchMapping(value = "/work-order-of-create-application/{workOrderId}/create")
    public BaseResponse createNewApplication(@PathVariable("workOrderId") Integer workOrderId, HttpServletRequest request) throws OperationException {
        log.info("start exec method [createNewApplication]. workOrderId:{}", workOrderId);
        AccountCommon accountCommon = accountService.getAccountCommon(request);
        orderService.createApplication(workOrderId);
        log.info("success exec method [createNewApplication].");
        return new BaseResponse(ConstantCode.SUCCESS);
    }

    /**
     * @param pageNumber
     * @param pageSize
     * @param status
     * @return
     */
    @GetMapping(value = "list")
    public BasePageResponse queryApplicationByPage(@RequestParam("pageNumber") Integer pageNumber,
                                                   @RequestParam("pageSize") Integer pageSize,
                                                   @RequestParam(value = "chainId", required = false) Integer chainId,
                                                   @RequestParam(value = "status", required = false) Set<Byte> status,
                                                   HttpServletRequest request) {
        log.info("start exec method [queryApplicationByPage]. pageNumber:{} pageSize:{} chainId:{} status:{}", pageNumber, pageSize, chainId, status);
        AccountCommon accountCommon = accountService.getAccountCommon(request);
        BasePageResponse response = applicationService.queryApplicationByPage(accountCommon.getPlatform(), accountCommon.getId(), accountCommon.getRoleName(), chainId, status, pageNumber, pageSize);
        log.info("success exec method [queryApplicationByPage]. result:{}", JsonUtils.objToString(response));
        return response;
    }

    /**
     * @param param
     * @param request
     * @return
     */
    @PostMapping(value = "addOrganization")
    public BaseResponse joinOrganization(@RequestBody @Valid ReqModifyAppOrg param, HttpServletRequest request) {
        log.info("start exec method [joinOrganization]. param:{}", JsonUtils.objToString(param));
        AccountCommon accountCommon = accountService.getAccountCommon(request);
        applicationService.joinOrganization(param.getApplicationId(), param.getOrgId());
        BaseResponse baseResponse = BaseResponse.initSuccess();
        log.info("success exec method [queryApplicationByPage]. result:{}", JsonUtils.objToString(baseResponse));
        return baseResponse;
    }

    /**
     * @param param
     * @param request
     * @return
     */
    @PostMapping(value = "removeOrganization")
    public BaseResponse removeOrganization(@RequestBody @Valid ReqModifyAppOrg param, HttpServletRequest request) {
        log.info("start exec method [removeOrganization]. param:{}", JsonUtils.objToString(param));
        AccountCommon accountCommon = accountService.getAccountCommon(request);
        applicationService.removeOrgFromApp(param.getApplicationId(), param.getOrgId());
        BaseResponse baseResponse = BaseResponse.initSuccess();
        log.info("success exec method [removeOrganization]. result:{}", JsonUtils.objToString(baseResponse));
        return baseResponse;
    }

    /**
     * 获取应用详情。
     *
     * @param applicationId
     * @return
     */
    @GetMapping(value = "/{applicationId}/detail")
    public BaseResponse getApplicationDetail(@PathVariable("applicationId") Integer applicationId) {
        log.info("start exec method [getApplicationDetail]. applicationId:{}", applicationId);
        TbApplication tbApplication = applicationManager.verifyApplicationId(applicationId);
        BaseResponse baseResponse = BaseResponse.initSuccess();
        baseResponse.setData(tbApplication);
        log.info("finish exec method [getApplicationDetail]. applicationId:{} result:{}", applicationId, JsonUtils.objToString(baseResponse));
        return baseResponse;
    }
}
